package com.cib.xagcjs.biz;

import com.alibaba.fastjson.JSONObject;
import com.cib.xagcjs.common.EcnyResponse;
import com.cib.xagcjs.common.EcnytPaymentRequest;
import com.cib.xagcjs.dal.EcnyPaymentNotifyMapper;
import com.cib.xagcjs.dal.MessageLogMapper;
import com.cib.xagcjs.dto.EcnyContractPayDTO;
import com.cib.xagcjs.dto.EcnyPaymentDTO;
import com.cib.xagcjs.utils.CryptoUtils;
import com.cib.xagcjs.utils.ResponseUtil;
import com.cib.xagcjs.utils.TimeUtil;
import com.cib.xagcjs.vo.EcnyPaymentListVO;
import com.cib.xagcjs.vo.EcnyPaymentVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Description: 数币通知实现层
 * Author: jingcaiqi1225@gmail.com
 * Date: 2024/2/22 9:10
 */
@Service
@Slf4j
public class EcnyPaymentNotifyService {

    @Autowired
    private ResponseUtil responseUtil;

    @Autowired
    private CryptoUtils cryptoUtils;

    @Autowired
    private MessageLogMapper messageLogMapper;

    @Autowired
    private EcnyPaymentNotifyMapper ecnyPaymentNotifyMapper;

    private Map<String, Objects> map;


    /**
     * 接收数币推送消息
     * @param req 消息内容
     * @return 统一返回报文
     */
    public String sendMessage(String req) {
        String s = cryptoUtils.decryptAndVerify(req);
        EcnyPaymentDTO data = JSONObject.parseObject(s, EcnyPaymentDTO.class);

        // 此处写推送后台业务
        // 接收的通知数据发给后台处理 (此处为模拟)

        // 判断是否存在冻结金额，如果存在直接调用冻结方法

        // 获取当前通知时间
        //yyyy-MM-dd HH:mm:ss
//        data.setNotifyTime(TimeUtil.getNowTime());
        log.info("推送报文日志打印：" + s);
        log.info("data数据日志打印：" + data);

        // 接收的消息入库通知主表
        if (ecnyPaymentNotifyMapper.insertNotify(data) > 0) {
            log.info("通知主表数据入库成功!");
            // 数币支付详情表循环入库
            List<EcnyContractPayDTO> contractPayments = data.getContractPayList();
            for (EcnyContractPayDTO contractPayment : contractPayments) {
                if (ecnyPaymentNotifyMapper.insetPaymentDto(contractPayment, data.getTransId()) > 0) {
                    log.info("{}数币支付明细入库成功!",contractPayment);
                } else {
                    log.info("{}数币支付明细入库失败!",contractPayment);
                }
            }
            // 存入消息记录表
            if (messageLogMapper.insertMessageLog(4,"数币付款指令通知",TimeUtil.getNowTime(),JSONObject.toJSONString(data)) > 0) {
                log.info("数币付款指令通知入库成功!");
            } else {
                log.info("数币付款指令通知入库失败!");
            }
        } else {
            log.info("通知主表数据入库失败!");
        }

        try {
            return cryptoUtils.encryptAndSign(responseUtil.getResponse(data.getTransId(), "1", ""));
        } catch (Exception e) {
            log.error("加密报文失败",e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 行方请求发送数币支付结果通知
     * @param req 请求报文
     * @return 返回结果
     */
    public String sendNotify(Map<String, Objects> req) throws Exception {
        Objects message = req.get("message");
        EcnytPaymentRequest request = JSONObject.parseObject(message.toString(), EcnytPaymentRequest.class);
        String sign = cryptoUtils.encryptAndSign(request.toString());
        // 模拟与区块链进行通信
        if (JSONObject.parseObject(cryptoUtils.decryptAndVerify(sign), EcnyResponse.class).getStatus().equals("1")) {
            return "OK";
        }
        return "FALSE";
    }

    /**
     * 添加数币支付明细表
     * @param contractPayment 数币支付详情
     * @return 执行影响的行数
     */
    public int insetPaymentDto(EcnyContractPayDTO contractPayment, String transId) {
        return ecnyPaymentNotifyMapper.insetPaymentDto(contractPayment, transId);
    }

    /**
     * 查询数币通知表主表支付状态改为 2 （已支付） 的 列表
     * @param status 支付状态
     * @return transId 列表
     */
    public List<EcnyPaymentVO> selectByTransId(int status) {
        return ecnyPaymentNotifyMapper.selectByTransId(status);
    }

    /**
     * 根据transId查询这组数据的支付总笔数
     * @param transId 交易唯一标识
     * @return 总笔数
     */
    public int selectTotalNum(String transId) {
        return ecnyPaymentNotifyMapper.selectTotalNum(transId);
    }

    /**
     * 根据这个批次的transId 获取下面所有 状态 3-付款成功，收款未确认 的列表
     * @param transId 批次号
     * @return 列表
     */
    public List<EcnyPaymentListVO> selectList(String transId) {
        return ecnyPaymentNotifyMapper.selectList(transId);
    }

    /**
     * 修改通知表状态为 3 已反馈
     * @param transId 交易唯一标识
     * @param status 状态
     */
    public void updateStatus(String transId, int status) {
        ecnyPaymentNotifyMapper.updateStatus(transId, status);
    }
}
